﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using BankApp.Models;
using CommonApp.Models;
using IBS.Bll;
using IBS.Model;
using IBS.ServiceContracts;

namespace BankApp.Controllers
{
    [Authorize(Roles = "operator")]
    public class TransfersController : Controller
    {
        private IKnowledgeBaseService knowledgeBaseService;
        private ICardService cardService;
        private IAccountService accountService;
        private ITransferService transferService;
        private IBillService billService;

        private OperationStep[] GetSteps(int clientId)
        {
            return new[] {
                new OperationStep { Uid="cardsMenuItem", Name = "Cards", GoTo = "/Transfers/Index/" + clientId.ToString() },
                new OperationStep() {
                    Uid="amountMenuItem",
                    Name = "Specify amount",
                    IsVisible = false,
                    GoTo = "/Transfers/SetAmount"
                },
                new OperationStep { Uid="homeMenuItem", Name = "Back", GoTo = "/Clients"}, };
        }
        
        public TransfersController()
        {
            var container = new IbsContainer();
            this.cardService = container.CardService;
            this.knowledgeBaseService = container.KnowledgeBaseService;
            this.accountService = container.AccountService;
            this.transferService = container.TransferService;
            this.billService = container.BillService;
        }

        public ActionResult Index(int id)
        {
            IEnumerable<Card> cards = null;
            try
            {
                var client = knowledgeBaseService.GetClientById(id);
                cards = cardService.GetClientsCard(client);//, c => !c.IsBlocked);
            }
            catch (BusinessException be)
            {
                ModelState.AddModelError("", be.Message);
            }
            ViewBag.Steps = GetSteps(id);
            ViewBag.ActiveStep = ViewBag.Steps[0];
            ViewBag.Transfer = new ExternalOperationModel { ClientId = id };
            ViewBag.AccountService = accountService;
            ViewBag.SelectedCardIndex = 0;
            return View(cards);
        }

        [HttpPost]
        public ActionResult SetAmount(ExternalOperationModel externalOperation)
        {
            var steps = GetSteps(externalOperation.ClientId);
            ViewBag.Steps = steps;
            steps[1].IsVisible = true;
            steps[2].IsVisible = true;
            ViewBag.Currencies = new[] {"USD", "BYR"};
            ViewBag.ActiveStep = steps[2];
            ViewBag.Transfer = externalOperation;
            ViewBag.EnsureSecurity = true;
            return View(externalOperation);
        }

        [HttpPost]
        public ActionResult Transfer(ExternalOperationModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    var transfer = model.Type == DepositOrWithdraw.Deposit
                        ? cardService.Deposit(model.CardNumber, model.Amount)
                        : cardService.Withdraw(model.CardNumber, model.Amount);

                    return View(transfer);
                }
                catch (BusinessException be)
                {
                    ModelState.AddModelError(be.Message, be.Message);
                    ViewBag.Errors = be.Message;
                }
            }
            var steps = GetSteps(model.ClientId);
            ViewBag.Steps = steps;
            steps[1].IsVisible = true;
            steps[2].IsVisible = true;
            ViewBag.ActiveStep = steps[2];
            ViewBag.Transfer = model;
            return View("SetAmount", model);
        }

        public ActionResult GetBill(int transferId)
        {
            var transfer = transferService.GetTransfers(t => t.Id == transferId).FirstOrDefault();
            var bill = billService.GenerateBill(transfer);
            string billFileName = billService.GetBill(bill);
            return File(billFileName, @"application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        }

        public ActionResult Block(string cardNumber, int clientId)
        {
            try
            {
                cardService.LockCard(cardNumber);
            }
            catch (BusinessException be)
            {
                ModelState.AddModelError("", be.Message);
            }

            return RedirectToAction("Index", new { id = clientId });
        }

        public ActionResult UnBlock(string cardNumber, int clientId)
        {
            try
            {
                cardService.UnlockCard(cardNumber);
            }
            catch (BusinessException be)
            {
                ModelState.AddModelError("", be.Message);
            }

            return RedirectToAction("Index", new{ id = clientId });
        }
    }
}
